import os
import yaml

from pyassured.core.project_path import config
from pyassured.core.logger import Log


class YamlConfigUtils():

    def __init__(self):

        self.__application_data = {}
        self.__config_file_path = None  # 记录配置文件路径
        self.__debug_mode = os.environ.get('CONFIG_DEBUG', 'false').lower() == 'true'
        self.__logger = Log()  # 初始化日志记录器

    def read_yaml(self, file_path):

        if not os.path.exists(file_path):
            raise FileNotFoundError("%s 文件不存在！" % file_path)
        with open(file_path, encoding='utf-8') as f:
            self.data = yaml.safe_load(f)
        return self.data

    def read_application_config(self, file_name):

        if self.__application_data is not None and len(self.__application_data) == 0:
            # 按优先级查找配置文件
            search_paths = [
                os.path.join(os.getcwd(), file_name),  # 当前工作目录
                os.path.join(os.path.dirname(os.getcwd()), file_name),  # 上级目录
                os.path.join(config.base_dir, file_name),  # 包目录
            ]

            yaml_config_path = None
            if self.__debug_mode:
                self.__logger.debug(f"开始查找配置文件: {file_name}")

            for path in search_paths:
                if self.__debug_mode:
                    self.__logger.debug(f"检查路径: {path}")
                if os.path.exists(path):
                    yaml_config_path = path
                    if self.__debug_mode:
                        self.__logger.debug(f"找到配置文件: {path}")
                    break

            if yaml_config_path is None:
                raise FileNotFoundError(
                    f"配置文件 '{file_name}' 未找到。已搜索路径：\n" +
                    "\n".join(f"  - {path}" for path in search_paths) +
                    "\n\n请确保配置文件存在于以上任一路径中。"
                )

            self.__config_file_path = yaml_config_path  # 记录配置文件路径
            data = self.read_yaml(yaml_config_path)

            if self.__debug_mode:
                self.__logger.debug(f"配置文件加载成功: {yaml_config_path}")
                self.__logger.debug(f"配置内容: {data}")

            # 验证配置文件格式
            self._validate_config(data)

            # 优先使用环境变量 TEST_ENV，如果没有则使用配置文件中的 env
            current_env = os.environ.get('TEST_ENV', data.get('env', 'test'))

            # 确保环境配置存在
            if current_env not in data['host']:
                raise ValueError(
                    f"环境 '{current_env}' 在配置文件的 host 配置中不存在。可用环境: {list(data['host'].keys())}")

            self.__application_data['host'] = data['host'][current_env]
            self.__application_data['headers'] = data.get('headers', {})

            # 数据库配置支持环境切换
            if 'dbconfig' in data:
                if isinstance(data['dbconfig'], dict) and current_env in data['dbconfig']:
                    # 如果数据库配置按环境分组
                    self.__application_data['dbconfig'] = data['dbconfig'][current_env]
                else:
                    # 如果数据库配置是全局的
                    self.__application_data['dbconfig'] = data['dbconfig']

            self.__application_data['debugMode'] = data['debugMode']

            # 读取超时配置
            self.__application_data['timeout'] = data.get('timeout', 30)

            # 读取重试配置
            if 'retry' in data:
                self.__application_data['retry'] = data['retry']
            else:
                # 默认重试配置
                self.__application_data['retry'] = {
                    'max_attempts': 1,  # 默认不重试
                    'delay': 1
                }

            self.__application_data['current_env'] = current_env  # 记录当前使用的环境
        return self.__application_data

    def get_config_file_path(self) -> str:
        """
        获取当前使用的配置文件路径
        
        Returns:
            str: 配置文件的绝对路径，如果未加载则返回None
        """
        return self.__config_file_path

    def reload_config(self, file_name: str = "application.yaml"):
        """
        重新加载配置文件
        
        Args:
            file_name: 配置文件名
        """
        self.__application_data = {}
        self.__config_file_path = None
        return self.read_application_config(file_name)

    def _validate_config(self, data):
        """
        验证配置文件格式
        
        Args:
            data: 配置文件数据
            
        Raises:
            ValueError: 配置文件格式不正确时抛出
        """
        required_fields = ['host']
        missing_fields = []

        for field in required_fields:
            if field not in data:
                missing_fields.append(field)

        if missing_fields:
            raise ValueError(
                f"配置文件缺少必要字段: {', '.join(missing_fields)}\n"
                f"请确保配置文件包含以下必要字段: {', '.join(required_fields)}"
            )

        # 验证 host 配置格式
        if not isinstance(data['host'], dict) or not data['host']:
            raise ValueError(
                "配置文件中的 'host' 字段必须是非空字典，格式如: {'test': 'http://example.com'}"
            )

        # 验证每个环境的 host 配置
        for env, host_url in data['host'].items():
            if not isinstance(host_url, str) or not host_url.strip():
                raise ValueError(
                    f"环境 '{env}' 的 host 配置必须是非空字符串"
                )

    def clear_application_data(self):

        self.__application_data = {}


yaml_config = YamlConfigUtils()
